home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / mcomm551.zip / ASYNC.DOC < prev    next >
Text File  |  1991-11-28  |  93KB  |  2,460 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.             ASYNCHRONOUS FUNCTIONS FOR MICROSOFT, TURBO, OR ZORTECH C
  7.  
  8.  
  9.             The LIB(s) on the included disk are libraries of serial
  10.          communications functions designed specifically for use with
  11.          Microsoft C, Turbo C / C++, and Zortech C / C++.  The regis-
  12.          tered version has LIBs for all memory models.  The shareware
  13.          version is small model only.
  14.  
  15.  
  16.                     --- Features of the library functions ---
  17.  
  18.             o Support for 16550 UART's FIFO mode of operation
  19.  
  20.             o Fully interrupt driven
  21.  
  22.             o Baud rates up to 115,200 baud
  23.  
  24.             o User defined transmit and receive ring buffer sizes.
  25.  
  26.             o Ring buffers may be in placed in FAR memory even in small
  27.               and medium model programs.
  28.  
  29.             o User defined port addresses, IRQ use, and interrupt vector
  30.               numbers.
  31.  
  32.             o Support for simultaneous operation of 2 ports.
  33.  
  34.             o Built in support for XON/XOFF and hardware flow control
  35.  
  36.             o Block transmit and receive functions
  37.  
  38.             o Receive buffer look ahead function
  39.  
  40.             o 100% assembler code for maximum speed
  41.  
  42.             o Totally compatible with Microsoft C, Turbo C, Zortech C,
  43.               and other C compilers that use standard Microsoft high
  44.               level language calling conventions.
  45.  
  46.  
  47.  
  48.          ---------------------------------------------------------------
  49.                 Mike Dumdei,  6 Holly Lane,  Texarkana TX  75503
  50.                 MCOMM5 (c) 1989, 1990, 1991  All Rights Reserved
  51.          ---------------------------------------------------------------
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.                       REGISTRATION AND DISTRIBUTION POLICY
  59.  
  60.             MCOMM5, the various versions of Smalterm, the ANSI video
  61.          routines, and other miscellaneous functions contained in the
  62.          COMM_x libraries are distributed as shareware.  If you use
  63.          these functions regularly please register them.
  64.  
  65.             Two types of registration are available for MCOMM5.  The
  66.          first is $25 and includes assembled libraries for all memory
  67.          models.  The $25 registration does not include source code.
  68.          The second type of registration is $45 and includes libraries
  69.          and source code.  Previous versions were $25 for source code
  70.          and libraries.  If you send $25 and want source code based on
  71.          previous offers, you will receive a previous version of the
  72.          source.  Registered users of versions prior to version 5 may
  73.          upgrade their libraries for $3 or upgrade source code version
  74.          for $10.
  75.  
  76.             Considerable time and effort has gone into developing and
  77.          debugging these routines.  If you are not a registered user and
  78.          have obtained a copy of the registered version, please take
  79.          time now to register the software or delete it.  The copy you
  80.          have is a registered version if it contains libraries for any
  81.          memory model other than small model or if any of the ASM source
  82.          code is included.
  83.  
  84.             This software is provided as is without warranty as to its
  85.          fitness for a particular use or being free of errors.  I assume
  86.          no liability for any loss or damages you may incur through its
  87.          use.  I will, however, make every effort to correct any
  88.          software errors that may exist, and provide you with a working
  89.          version.
  90.  
  91.             I will continue to assist registered and non-registered
  92.          users whenever possible.  If you have any problems using these
  93.          routines or questions, I may be contacted at:
  94.  
  95.             North East Texas DataLink --  903 838-6713 (modem)
  96.                                           FIDO net:  1:19/128
  97.  
  98.             Mike Dumdei               --  903 838-8307 (voice)
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.                                  GETTING STARTED
  106.  
  107.          All functions included in this library are listed on the fol-
  108.          lowing pages in alphabetical order.  The basic functions needed
  109.          to begin are: async_open, async_tx, async_rx, and async_close.
  110.  
  111.          Functions are also available to support XON/XOFF and hardware
  112.          flow control, the 16550 UART, block transmit and receive,
  113.          receive buffer look ahead, and several other features.
  114.  
  115.          All functions take a pointer to an ASYNC structure for one of
  116.          its arguments.  This structure is defined in COMM.H.  It
  117.          may be helpful to think of this structure as being similar to
  118.          the standard C library 'FILE *'.
  119.  
  120.          If you have been using versions of these routines prior to
  121.          version 5.00, there have been some changes made that will
  122.           require you to make some modifications to any existing code
  123.          before it can be used with the new libraries.  The main
  124.          differences are:
  125.  
  126.             > Async_open takes different parameters.  Also, instead
  127.               of the open function automatically allocating the ring
  128.               buffers for you, you provide the ring buffers.
  129.  
  130.             > All functions now take a pointer to an ASYNC structure
  131.               as the first argument rather than 0 (COM1) or 1 (COM2).
  132.  
  133.             > LITES is no longer supported.
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.                             NOTES ON 16550 FIFO MODE
  141.  
  142.             The 16550 UART is automatically detected and enabled when
  143.          async_open is called.  If, for some reason, you want to operate
  144.          a 16550 UART in non-FIFO mode, automatic detection and use can
  145.          be disabled.  See async_open for more information.
  146.  
  147.  
  148.                           --- Use of receiver FIFOs ---
  149.  
  150.             The receiver trigger level may be programmed for 1, 4, 8, or
  151.          14 bytes by the async_FIFOrxlvl function.  When a port is first
  152.          opened the trigger is set to 1 byte.  There are 3 reasons why I
  153.          chose to default to a 1 byte receive trigger level.
  154.  
  155.             1) While a higher trigger level results in less CPU
  156.                overhead, it also provides less overrun protection if the
  157.                CPU is slow to respond.  For example, with a 1 byte
  158.                trigger level the 16550 -- when it generates an interrupt
  159.                -- can hold 15 more characters in its FIFOs before the
  160.                CPU responds.  With a 14 byte trigger level it will only
  161.                have room for 2 more characters.
  162.  
  163.             2) The MCOMM interrupt functions completely empty the
  164.                receiver FIFOs every time an interrupt occurs.  If the
  165.                CPU is slow to respond, the interrupt handler will
  166.                process 2,3,4.. characters (whatever is in the FIFOs)
  167.                whenever it does get control so the data still gets
  168.                buffered if the CPU isn't able to keep up.
  169.  
  170.             3) Setting the trigger level at higher trigger levels when
  171.                displaying incoming data to the screen will result in a
  172.                jerky looking display, especially at low baud rates.
  173.                Again, this is because MCOMM empties the buffer
  174.                completely when it processes the interrupt.  With a
  175.                trigger level other than 1, data stacks up in the FIFOs
  176.                until the trigger level is reached.  When the interrupt
  177.                finally occurs, all the data in the FIFOs is pulled out
  178.                and made available to the higher level functions at
  179.                one time.  The result is your code sits for 4, 8, or 14
  180.                bytes (whatever the trigger is) and then puts those bytes
  181.                on the screen in a burst.  It looks rough at low baud
  182.                rates.  At 9600 baud and above you could probably get by
  183.                with a slightly higher trigger level.
  184.  
  185.             For best use of the receive FIFOs, stick with 1 byte trigger
  186.          level when displaying data to the screen.  If your application
  187.          does not display the data or uses a high baud rate, you may
  188.          want to experiment with setting it to either 4 or 8 bytes.
  189.  
  190.  
  191.                           --- Use of transmit FIFOs ---
  192.  
  193.             The MCOMM transmit interrupt handler takes a parameter (set
  194.          by async_FIFOtxlvl) that is the maximum number of bytes to load
  195.          into the transmit FIFOs at one time.  The default value for
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.                             NOTES ON 16550 FIFO MODE
  203.  
  204.          this parameter is 3 bytes.  The reason for not loading up the
  205.          FIFOs to maximum capacity (16 bytes) is flow control.  The
  206.          16550 UART will continue to transmit characters in its FIFOs
  207.          regardless of the state of CTS, DSR, or CD, or if an XOFF is
  208.          received.  It is totally up to the software to respond to
  209.          requests for flow control.  If the FIFOs are loaded with more
  210.          bytes than the receiver can handle when it invokes flow
  211.          control, the receiver gets overwritten.  There is a bit that
  212.          can be sent to the UART to flush the transmit FIFOs but then it
  213.          is impossible to tell what was flushed and what was sent.  The
  214.          solution is to not the load the FIFOs up so full.  If the
  215.          receiving device can handle more than 3 characters of overrun,
  216.          use a larger value.  If the application does not require flow
  217.          control, you can use a 16 byte level with no problems.
  218.  
  219.             Another factor to consider concerning the transmit FIFO byte
  220.          level is that (from the NS Data Communications/LAN/UART
  221.          Handbook) the transmit FIFO empty indication will be delayed by
  222.          1 character time minus the last stop bit until there are at
  223.          least 2 bytes in the transmit FIFOs simultaneously for the
  224.          current transmit operation.  After the 2 byte requirement is
  225.          met the transmit interrupt occurs immediately when the transmit
  226.          FIFOs empty.  Using a value of 3 or above (1 byte for the
  227.          transmit shift register and 2 for the FIFO registers)
  228.          guarantees the interrupt delay is deactivated.  Once the '2
  229.          bytes in the FIFOs' requirement is met, the transmit byte level
  230.          can be reduced if necessary.
  231.  
  232.  
  233.                   --- Problems with Western Digital 16550s ---
  234.  
  235.          The following problems DO NOT apply to the National Semicon-
  236.          ductor version of the 16550.  Neither are they unique to MCOMM.
  237.  
  238.          Western Digital 16550 UARTs have two problems you should be
  239.          aware of if your application will be ran on system that uses
  240.          this chip.
  241.  
  242.          The first of these only shows up under the following
  243.          conditions:
  244.  
  245.             1) The UART is in FIFO mode.
  246.             2) A low baud rate is being used.
  247.             3) The transmitter is initially empty.
  248.             4) A block of data longer than 16 to 18 bytes (depth of the
  249.                FIFOs plus 1 or 2 for what gets out while the FIFOs are
  250.                being filled up) is sent to the chip.
  251.  
  252.          Under these conditions the WD16550 UART will momentarily fail
  253.          to recognize the FIFOs are full and continue to generate
  254.          transmit interrupts.  It also fails to reset the 'Transmit Hold
  255.          Register Empty' bit making it impossible for the software to
  256.          detect a full FIFO condition.  The result is the software keeps
  257.          sending data to the chip, overrunning the FIFOs.  What you will
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.                             NOTES ON 16550 FIFO MODE
  265.  
  266.          see is, the first 16 to 18 bytes transmitted correctly, a
  267.          missing block of data, and then the remainder of the block also
  268.          correct.  This can be verified by trying to send blocks of data
  269.          through this chip (WD16550) at a low baud rate with any
  270.          software that enables the FIFOs.  How low of a baud rate is low
  271.          enough to cause the problem depends on the particular chip and
  272.          how fast the CPU and software can supply data to the chip.
  273.          With MCOMM, a 20 MHZ 386, and the TxByteCnt at the default
  274.          level of 3, the chip I was testing would not work in FIFO mode
  275.          below 9600 baud.  On the same system using different software,
  276.          it worked as low as 4800 baud.  On a 12 MHZ 286, MCOMM would
  277.          work at 4800 and above while the other software worked at 2400
  278.          and above.
  279.  
  280.          For publicly distributed applications, I recommend you do one
  281.          or more of the following:
  282.  
  283.             1) Provide an option in your program to allow the end user
  284.                to operate a 16550 with the FIFOs disabled.  When the
  285.                FIFOs are disabled, all baud rates work.  ORing the
  286.                ComBase parameter of async_open with 0x4000 will force
  287.                FIFO mode off.
  288.             2) Provide an option in your program to allow setting the
  289.                TxByteCnt level (async_FIFOtxlvl) to a lower value.  This
  290.                will help slightly.
  291.  
  292.             3) Put a flag in your program the end user can set to let
  293.                you know you are dealing with a WD16550.
  294.  
  295.             4) State your application does not support the Western
  296.                Digital version of the 16550 at low baud rates.
  297.  
  298.  
  299.          The second problem with the WD16550 is that if the 'Clear to
  300.          Send' signal is not connected it can, under some conditions,
  301.          cause the 'Delta Clear to Send' bit in the Modem Status
  302.          Register to become set and it will not reset.  I did not
  303.          research the problem enough to know if the 'locked bit' only
  304.          occurs when MSR interrupts are enabled, whether other floating
  305.          MSR input signals can cause the same problem, if all WD16550's
  306.          have the problem, or that is unique to the Western Digital chip
  307.          (considering the FIFO overrun problem, I assume it is unique).
  308.  
  309.          With a properly functioning UART, reading the MSR register will
  310.          reset all the 'delta bits' and clear any interrupts.  With the
  311.          chip I had, I tried everything I could think of to clear the
  312.          interrupt and nothing worked except the ON/OFF switch.  I tried
  313.          clearing interrupts and reading the MSR multiple times checking
  314.          to see if the bit reset with interrupts off (it didn't),
  315.          disabling Modem Status interrupts via the Interrupt Enable
  316.          Register and then reading the MSR register (didn't work), FIFO
  317.          mode on / FIFO mode off (no difference), keyboard reboot of the
  318.          computer (didn't fix it), shut the computer off and turn it
  319.          back on (that fixed it).
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.                             NOTES ON 16550 FIFO MODE
  327.  
  328.          After encountering this problem and having the system lock up,
  329.          I added code to MCOMM's interrupt driver so that it would quit
  330.          trying to clear an interrupt after 1000 attempts.  It then sets
  331.          a new port structure member 'IERVal' to zero as an indicator
  332.          the port is locked up.  Normally 'IERVal' will be set to the
  333.          current value of the Interrupt Enable Register.  If you try to
  334.          open a port that is in a stuck interrupt condition, async_open
  335.          now returns R_UARTERR.  In addition, options were added to open
  336.          a port without enabling Modem Status interrupts or Line Status
  337.          interrupts or both.  ORing the ComBase parameter of async_open
  338.          with 0x2000 disables MSR interrupts.  ORing with 0x1000
  339.          disables LSR interrupts.  So far I have encountered no reason
  340.          for disabling LSR interrupts.  Disabling MSR interrupts
  341.          prevents the lock up problem but has the side effect of causing
  342.          all functions and variables that use Modem Status signals to be
  343.          invalid.  This includes hardware handshake and carrier detect.
  344.  
  345.          I have probably over emphasized the Modem Status lock up
  346.          problem and my personal opinion is that it is not that serious.
  347.          I considered totally disregarding it since it has a simple
  348.          solution and that is to connect all Modem Status input signals
  349.          to some driving signal (wire the RS232 cable right).  Unused
  350.          signals can be connected to a driving signal on the computer
  351.          end if necessary.  Also it may be isolated to one defective
  352.          chip.  I tested two WD16550s and the problem only showed up on
  353.          one of them during my testing.  Because the computer totally
  354.          locked up when this happened though, I decided to go ahead and
  355.          program for the possibility.  At least control of the computer
  356.          is regained and you can tell the user he needs a properly wired
  357.          RS232 cable or his UART is broke and then exit gracefully.
  358.          This will probably show up very very rarely so don't be too
  359.          concerned about it.  In closing, I would like to point out
  360.          again that these problems are a fault of the WD16550 and are
  361.          not unique to MCOMM.
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.          async_16550
  369.          ---------------------------------------------------------------
  370.  
  371.          Purpose: Check if 16550 UART was detected in system.
  372.  
  373.          Format:  int async_16550(port);
  374.                    ASYNC *port;       Pointer to ASYNC structure
  375.  
  376.          Example:
  377.  
  378.                   ASYNC *port;
  379.                   int is_16550;
  380.  
  381.                   is_16550 = async_16550(port);
  382.  
  383.          Returns: Returns zero if a 16550 is not in the system or the
  384.                   'ignore 16550 bit' was set when async_open was called.
  385.                   Returns NZ if a 16550 was found.  Async_open must be
  386.                   called before this function is valid.  If a 16550 is
  387.                   found, it will be placed in the FIFO mode of operation
  388.                   by async_open unless '16550 detect' was overridden or
  389.                   the force FIFOs off option was selected.
  390.  
  391.          Remarks: This function is implemented as a macro.
  392.  
  393.                   See async_open.
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.          async_breakrxd
  401.          ---------------------------------------------------------------
  402.  
  403.          Purpose: Checks if a break signal has been received.
  404.  
  405.          Format:  int async_breakrxd(port);
  406.                    ASYNC *port;       Pointer to ASYNC structure
  407.  
  408.          Example:
  409.  
  410.                   ASYNC *port;
  411.                   int break_status;
  412.  
  413.                   break_status = async_breakrxd(port);
  414.  
  415.  
  416.          Returns: If a break signal has been received the function
  417.                   returns a non-zero value.  If a break has not been
  418.                   detected, zero is returned.
  419.  
  420.          Remarks: Once a break signal has been detected, this function
  421.                   continually returns non-zero values until async_reset
  422.                   is called.  If a break is received, a line status
  423.                   register interrupt is generated.  The interrupt
  424.                   handler sets a bit in the Stat1 port structure member.
  425.                   The async_breakrxd function is a macro that checks the
  426.                   status of this bit.
  427.  
  428.                   See also async_reset, async_rx, async_stat,
  429.                   async_sndbrk.
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.          async_carrier
  437.          ---------------------------------------------------------------
  438.  
  439.          Purpose: Check for the presence of a carrier.
  440.  
  441.          Format:  int async_carrier(port);
  442.                    ASYNC *port;       Pointer to ASYNC structure
  443.  
  444.          Example:
  445.  
  446.                   ASYNC *port;
  447.                   int carrier_status;
  448.  
  449.                   carrier_status = async_carrier(port);
  450.  
  451.  
  452.          Returns: A non-zero value is returned if a carrier is present.
  453.                   If the carrier detect line is LOW, zero is returned.
  454.  
  455.          Remarks: This function is implemented as a macro.  See also
  456.                   async_rx and async_stat.
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.          async_close
  464.          ---------------------------------------------------------------
  465.  
  466.          Purpose: Closes a port opened by async_open.
  467.  
  468.          Format:  int async_close(port);
  469.                    ASYNC *port;    Pointer to ASYNC structure
  470.  
  471.          Example:
  472.  
  473.                   ASYNC port;
  474.                   async_close(&port);
  475.  
  476.          Returns: No return value
  477.  
  478.          Remarks: Do not attempt to close an unopened port.  Some
  479.                   minimal checking is done internally by async_close in
  480.                   an attempt to detect whether or not the specified port
  481.                   is actually opened.  If an unopened port makes it past
  482.                   those checks and the main close routine is entered,
  483.                   the system may lock up (immediately, 2 hours later, or
  484.                   never).  When a port is closed the UART registers,
  485.                   interrupt controller mask, and interrupt vectors are
  486.                   restored to the value they had when async_open was
  487.                   called.  It is possible to close the port and leave
  488.                   various signals (DTR for one) in the state you desire
  489.                   rather than in their initial state.  See async_dtr and
  490.                   async_rts for some examples on how to do this.
  491.  
  492.                   The B_ORGFIFO bit in the ASYNC 'Stat3' structure
  493.                   member is used by async_close to return the 16550 --
  494.                   if present -- to the mode it was in when async_open
  495.                   was called.  FIFOs may be 'forced' to remain enabled
  496.                   or 'forced' to be disabled when closing the port by
  497.                   first setting or resetting this bit.  Ex:
  498.  
  499.                     Force off:    port->Stat3 &= ~B_ORGFIFO;
  500.                                   async_close(port);
  501.  
  502.                     Force on:     port->Stat3 |= B_ORGFIFO;
  503.                                   async_close(port);
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.          async_cts
  511.          ---------------------------------------------------------------
  512.  
  513.          Purpose: Check status of the Clear to Send signal.
  514.  
  515.          Format:  int async_cts(port);
  516.                    ASYNC *port;       Pointer to ASYNC structure
  517.  
  518.          Example:
  519.  
  520.                   ASYNC *port;
  521.                   int cts_status;
  522.  
  523.                   cts_status = async_cts(port);
  524.  
  525.          Returns: Returns zero if Clear To Send is LOW.  If CTS is HIGH,
  526.                   a non-zero value is returned.
  527.  
  528.          Remarks: This function is implemented as a macro.
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.          async_dsr
  536.          ---------------------------------------------------------------
  537.  
  538.          Purpose: Check status of the Data Set Ready signal.
  539.  
  540.          Format:  int async_dsr(port);
  541.                    ASYNC *port;       Pointer to ASYNC structure
  542.  
  543.          Example:
  544.  
  545.                   ASYNC *port;
  546.                   int dsr_status;
  547.  
  548.                   dsr_status = async_dsr(port);
  549.  
  550.          Returns: Returns zero if Data Set Ready is LOW.  If DSR is
  551.                   HIGH, a non-zero value is returned.
  552.  
  553.          Remarks: This function is implemented as a macro.
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.          async_dtr
  561.          ---------------------------------------------------------------
  562.  
  563.          Purpose: Set or reset the Data Terminal Ready signal.
  564.  
  565.          Format:  void async_dtr(port, DTRflag);
  566.                    ASYNC *port;       Pointer to ASYNC structure
  567.                    int DTRflag;       Set/Reset DTR flag
  568.  
  569.          Example:
  570.  
  571.                   ASYNC *port;
  572.  
  573.                   if (WantToDropDTR)
  574.                       async_dtr(port, 0);
  575.                   else if (WantDTRhigh)
  576.                       async_dtr(port, 1);
  577.  
  578.  
  579.          Returns: No return value
  580.  
  581.          Remarks: This signal is set HIGH when a port is first opened.
  582.                   When the port is closed, it is restored to the cond-
  583.                   ition it was in when the port was opened.  To force
  584.                   DTR low when a port is closed, regardless of its state
  585.                   when the port was opened, AND the port member, OldMCR,
  586.                   with NOT B_DTR.  To force DTR to remain high when the
  587.                   port is closed, OR OldMCR with B_DTR.
  588.  
  589.                     Force low:    port->OldMCR &= ~B_DTR;
  590.                                   async_close(port);
  591.  
  592.                     Force high:   port->OldMCR |= B_DTR;
  593.                                   async_close(port);
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.          async_FIFOrxlvl  <5.20 addition>
  601.          ---------------------------------------------------------------
  602.  
  603.          Purpose: Set the 16550 UART's receive trigger level.
  604.  
  605.          Format:  void async_FIFOrxlvl(port, trigger_lvl);
  606.                    ASYNC *port;       Pointer to ASYNC structure
  607.                    int trigger_lvl;   Rx FIFO interrupt trigger level
  608.  
  609.          Example:
  610.  
  611.                   ASYNC *port;
  612.  
  613.                    /* set the receiver trigger level to 8 bytes */
  614.                   async_FIFOrxlvl(port, 8);
  615.  
  616.          Returns: No return value
  617.  
  618.          Remarks: Valid values for 'trigger_lvl' are 1, 4, 8, and 14
  619.                   bytes.  When a port with a 16550 UART is first opened,
  620.                   the trigger level is set to 1 byte.  See the
  621.                   discussion on 'Use of receiver FIFOs' at the beginning
  622.                   of this document.  This function has no effect if the
  623.                   FIFOs were not enabled when async_open was called.
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.          async_FIFOtxlvl  <5.20 addition>
  631.          ---------------------------------------------------------------
  632.  
  633.          Purpose: Set the number of bytes loaded into the 16550 UART's
  634.                   transmit FIFOs when a transmit interrupt occurs.
  635.  
  636.          Format:  void async_FIFOtxlvl(port, bytes);
  637.                    ASYNC *port;       Pointer to ASYNC structure
  638.                    int bytes;         # of bytes to load into tx FIFOs
  639.  
  640.          Example:
  641.  
  642.                   ASYNC *port;
  643.  
  644.                    /* set the transmit FIFO byte level to 16 bytes */
  645.                   async_FIFOrxlvl(port, 16);
  646.  
  647.          Returns: No return value
  648.  
  649.          Remarks: Valid values for 'bytes' are 1 through 16 bytes.  When
  650.                   a port with a 16550 UART is first opened, the transmit
  651.                   level byte count is set to 3 bytes.  See the
  652.                   discussion on 'Use of transmit FIFOs' at the beginning
  653.                   of this document.  This function has no effect if the
  654.                   FIFOs were not enabled when async_open was called.
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.          async_ignerr
  662.          ---------------------------------------------------------------
  663.  
  664.          Purpose: Set or reset 'ignore characters with errors' bit
  665.  
  666.          Format:  void async_ignerr(port, flag);
  667.                    ASYNC *port;       Pointer to ASYNC structure
  668.                    int flag;          Set/Reset flag
  669.  
  670.          Example:
  671.  
  672.                   ASYNC *port;
  673.  
  674.                   if (WantToDiscardErrChars)
  675.                       async_ignerr(port, 1);
  676.                   else if (WantToKeepErrChars)
  677.                       async_ignerr(port, 0);
  678.  
  679.  
  680.          Returns: No return value
  681.  
  682.          Remarks: This function sets the bit that determines what hap-
  683.                   pens to received characters that have parity or fram-
  684.                   ing errors.  If the function is called with the flag
  685.                   set to one, incoming characters that have framing or
  686.                   parity errors are discarded -- they do not get put
  687.                   into the receive ring buffer.  If the flag is 0, char-
  688.                   acters with errors are not ignored, they are put into
  689.                   the ring buffer.  The error bits in Stat1 that reflect
  690.                   these error conditions are set regardless of the
  691.                   setting of the discard flag.  When a port is first
  692.                   opened, the flag is set to 0.  This function is imple-
  693.                   mented as a macro.
  694.  
  695.                   See also async_stat.
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.          async_msr
  703.          ---------------------------------------------------------------
  704.  
  705.          Purpose: Get the contents of the Modem Status Register.
  706.  
  707.          Format:  int async_msr(port);
  708.                    ASYNC *port;       Pointer to ASYNC structure
  709.  
  710.          Example:
  711.  
  712.                   ASYNC *port;
  713.                   int MSRcontents;
  714.  
  715.                   MSRcontents = async_msr(port);
  716.  
  717.  
  718.          Returns: The contents of the Modem Status Register.
  719.  
  720.          Remarks: This function is a macro that returns the port struc-
  721.                   ture member, MSRVal.  This value is initialized when a
  722.                   port is first opened and then updated any time a modem
  723.                   status interrupt occurs.  The reason the MSR is not
  724.                   read directly is to avoid inadvertently intercepting a
  725.                   pending MSR interrupt.  All bits returned except for
  726.                   the delta bits reflect the true current status.
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.          async_msrflow  <5.50 modified>
  734.          ---------------------------------------------------------------
  735.  
  736.          Purpose: Enables or disables hardware flow control.
  737.  
  738.          Format:  void async_msrflow(port, flowmask);
  739.                    ASYNC *port;       Pointer to ASYNC structure
  740.                    int flowmask;      Bit mapped flow control mask
  741.  
  742.          Example:
  743.  
  744.                   ASYNC *port;
  745.  
  746.                   if (enable_RTS_CTS_handshake)
  747.                       async_msrflow(port, B_CTS);
  748.                   else if (disable_handshake)
  749.                       async_msrflow(port, 0);
  750.  
  751.          Returns: No return value
  752.  
  753.          Remarks: The flow mask is a bit mapped value of the signal that
  754.                   is monitored by the receiver when performing flow
  755.                   control.  Bits that may be monitored are B_CTS, B_DSR,
  756.                   and B_CD.  This provides capability for RTS/CTS hand-
  757.                   shake, DTR/DSR handshake, and handshaking with the
  758.                   carrier detect line.  To monitor multiple signals, OR
  759.                   the bits together.  Both hardware flow control and
  760.                   XON/XOFF flow control may be enabled at the same time.
  761.  
  762.                   Beginning with version 5.50, ORing B_RTS into the
  763.                   'flowmask' parameter, will cause the RTS signal to be
  764.                   driven low whenever the receive buffer exceeds the
  765.                   XoffTrip point.  RTS will automatically return to its
  766.                   normal condition when the receive buffer empties to a
  767.                   point below the XonTrip level.  Both XOFF/XON and RTS
  768.                   flow control share the same trip point variable but
  769.                   may be activated separately or together.  Do not get
  770.                   RTS and CTS confused.  Use CTS to keep the computer
  771.                   from overrunning a device (e.g. sending to a modem
  772.                   with a locked baud rate).  Use RTS to keep from
  773.                   getting ran over by a device (receiving from a high
  774.                   speed modem using a slow computer).
  775.  
  776.                   See async_xflow.
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.          async_open  <5.40 modified -- see Remarks at end of function>
  784.          ---------------------------------------------------------------
  785.  
  786.          Purpose: Initializes the hardware, interrupt vector, and ASYNC
  787.                   port structure for interrupt driven operation.
  788.  
  789.          Format:
  790.                   int async_open(port, base, irqmask, vctrnbr, params);
  791.                    ASYNC *port;   Pointer to ASYNC structure
  792.                    int base;      Base port address of UART chip
  793.                    int irqmask;   8259 mask value for selected IRQ line
  794.                    int vctrnbr;   Number of selected interrupt vector
  795.                    char *params;  Baud, parity, data, & stop bits in
  796.                                    string format
  797.  
  798.          Entry:   Before calling this function you must allocate ring
  799.                   buffer memory and pre-initialize the following ASYNC
  800.                   structure members:
  801.  
  802.                    RxSize : the size that you want the receive ring
  803.                       buffer to be.  The memory allocated or set aside
  804.                       for the receive ring buffer must be contiguous
  805.                       with the memory used for the transmit  ring
  806.                       buffer.  In most cases (RxSize + TxSize) bytes
  807.                       will be allocated using some form of malloc.
  808.                       A function to do this is included in the examples.
  809.                       The combined size of RxSize + TxSize can not
  810.                       exceed 32K - 1.
  811.  
  812.                    TxSize : the size of the transmit buffer in bytes.
  813.                       As stated above, the transmit and receive buffers
  814.                       for each individual port must be allocated as one
  815.                       contiguous block.
  816.  
  817.                    RingSeg: the segment address of the memory allocated
  818.                       for the receive and transmit buffers.  FAR memory
  819.                       can be used for the receive and transmit buffers
  820.                       by using your compiler library's version of FAR
  821.                       malloc and putting the segment portion (high 16
  822.                       bits) of the returned memory pointer in RingSeg.
  823.                       If you are using a NEAR data model program and
  824.                       want NEAR ring buffers, set RingSeg equal to 0.
  825.                       With RingSeg set to zero, the open function will
  826.                       use the DS segment register for RingSeg.  Using
  827.                       FAR ring buffers causes no loss of performance.
  828.  
  829.                   RingOfst: the offset address of the memory allocated
  830.                       for the receive and transmit buffers.  This value,
  831.                       in conjunction with the RxSize and TxSize vari-
  832.                       ables, is used to set up the receive and transmit
  833.                       ring buffers.
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.          async_open
  841.          ---------------------------------------------------------------
  842.  
  843.                   THE FOLLOWING FUNCTION IS INCLUDED WITH MCOMM5 AND IS
  844.                   RECOMMENDED FOR ALLOCATING RING BUFFER MEMORY AND
  845.                   INITIALIZING THE ABOVE VARIABLES.
  846.  
  847.          #if defined (__TURBOC__)         /* Turbo C */
  848.             #include <alloc.h>
  849.             #define _fmalloc farmalloc
  850.          #elif defined (__ZTC__)          /* Zortech C */
  851.             #include <dos.h>
  852.             #include <stdlib.h>
  853.             #define _fmalloc farmalloc
  854.          #else                            /* Microsoft C */
  855.             #include <malloc.h>
  856.          #endif
  857.  
  858.          int AllocRingBuffer(
  859.           ASYNC *port,                  /* pointer to port structure */
  860.           int rxsize,      /* number bytes to use for receive buffer */
  861.           int txsize,     /* number bytes to use for transmit buffer */
  862.           int useFARmem)    /* flag set if using FAR mem for buffers */
  863.          {
  864.             unsigned long memptr;
  865.             int memsize;
  866.  
  867.             memsize = rxsize + txsize;
  868.  
  869.             if (useFARmem || sizeof(char *) == 4)/* if FAR Ring bufs */
  870.                memptr = (unsigned long)_fmalloc(memsize);
  871.             else                  /* if Ring buffers use NEAR memory */
  872.                memptr = (unsigned long)(unsigned int)malloc(memsize);
  873.  
  874.              /* pre-initialize 4 required structure members */
  875.             port->RxSize = rxsize;            /* receive buffer size */
  876.             port->TxSize = txsize;           /* transmit buffer size */
  877.             port->RingSeg = (int)(memptr >> 16);          /* SEG adr */
  878.             port->RingOfst = (int)memptr;            /* OFST address */
  879.             if (memptr == 0L)
  880.                return 0;          /* return 0 if no memory available */
  881.             return 1;                   /* return 1, had some memory */
  882.          }
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.          async_open
  890.          ---------------------------------------------------------------
  891.  
  892.          Example 1:
  893.  
  894.             /*
  895.                Open COM1 at 2400,N,8,1 using FAR ring buffers. COM1 is
  896.                defined in COMM.H as:  0x3f8, 0x10, 12.  It is not
  897.                necessary to check the return value of AllocRingBuffer
  898.                since async_open will return R_NOMEM if the memory
  899.                allocation function fails.
  900.             */
  901.  
  902.             #include "comm.h"
  903.  
  904.             ASYNC port;
  905.             int rcode;
  906.  
  907.             AllocRingBuffer(&port, 24000, 8000, 1);
  908.  
  909.             rcode = async_open(&port, COM1, "2400N81");
  910.           /**  or
  911.             rcode = async_open(&port, 0x3f8, 0x10, 12, "2400N81");
  912.            **  or
  913.             rcode = async_open(&port, 0x3f8, IRQ4, VCTR4, "2400N81");
  914.            **/
  915.  
  916.             if (rcode != R_OK)
  917.             {
  918.                 printf("\nAsync_open failed, exit code = %d", rcode);
  919.                 exit(rcode);
  920.             }
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.          async_open
  928.          ---------------------------------------------------------------
  929.  
  930.          Example 2:
  931.  
  932.             /*
  933.                Open a port located at 0x2e0 that uses IRQ3.  In this
  934.                case NEAR ring buffers are specified and the memory for
  935.                the port structure is obtained using malloc.  See the
  936.                AllocRingBuffer function described previously.
  937.             */
  938.  
  939.             #include "comm.h"
  940.  
  941.             ASYNC *port;
  942.             int rcode;
  943.  
  944.             if ((port = (ASYNC *)malloc(sizeof ASYNC)) == NULL)
  945.             {
  946.                 printf("\nNot enough memory");
  947.                 exit(R_NOMEM);
  948.             }
  949.  
  950.             AllocRingBuffer(port, 4096, 1200, 0);
  951.  
  952.             rcode = async_open(port, 0x2e0, IRQ3, VCTR3, "115200E71");
  953.  
  954.             if (rcode != R_OK)
  955.             {
  956.                 printf("\nAsync_open failed, exit code = %d", rcode);
  957.                 exit(rcode);
  958.             }
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.          async_open
  966.          ---------------------------------------------------------------
  967.  
  968.          Example 3:
  969.  
  970.             /*
  971.                Open both COM1 and COM2 at the same time.  You can open
  972.                two ports at once as long as they don't share the same
  973.                IRQ line or interrupt vector.
  974.             */
  975.  
  976.             #include "comm.h"
  977.  
  978.             ASYNC ports[2], *port[2];
  979.             int rcode;
  980.  
  981.             port[0] = &ports[0], port[1] = &ports[1];
  982.  
  983.             AllocRingBuffer(port[0], 10240, 10240, 1);
  984.             rcode = async_open(port[0], COM1, "9600N81");
  985.             if (rcode != R_OK)
  986.             {
  987.                 printf("\nAsync_open failed, exit code = %d", rcode);
  988.                 exit(rcode);
  989.             }
  990.  
  991.             AllocRingBuffer(port[1], 10240, 10240, 1);
  992.             rcode = async_open(port[1], COM2, "1200E71");
  993.             if (rcode != R_OK)
  994.             {
  995.                 printf("\nAsync_open failed, exit code = %d", rcode);
  996.                 exit(rcode);
  997.             }
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.          async_open
  1005.          ---------------------------------------------------------------
  1006.  
  1007.          Example 4:
  1008.  
  1009.             /*
  1010.                Open COM1 using its current baud, parity, data, and
  1011.                stop bit settings.  The port structure member, BPDSstr,
  1012.                will reflect those settings after calling async_open.
  1013.             */
  1014.  
  1015.             #include "comm.h"
  1016.  
  1017.             ASYNC *port;
  1018.             int rcode;
  1019.  
  1020.              /* alloc port structure & ring buffer memory */
  1021.             port = malloc(sizeof(ASYNC));
  1022.             AllocRingBuffer(port, 4096, 2048, 1);
  1023.  
  1024.              /* empty parameter string causes port to be opened at
  1025.                 its current settings  */
  1026.             rcode = async_open(port, COM1, "");
  1027.  
  1028.             if (rcode != R_OK)
  1029.             {
  1030.                 printf("\nAsync_open failed, exit code = %d", rcode);
  1031.                 exit(rcode);
  1032.             }
  1033.  
  1034.             printf(
  1035.              "\nBaud, parity, data, stop bits = %s\n", port->BPDSstr);
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.          async_open
  1043.          ---------------------------------------------------------------
  1044.  
  1045.          Returns:
  1046.  
  1047.                   R_OK (0) - the port was opened with no errors.
  1048.  
  1049.                   R_NOMEM - a NULL pointer was passed as the address
  1050.                       of the ring buffers.  Probable causes are either
  1051.                       failing to initialize the port structure ring
  1052.                       buffer variables or assigning the RingSeg and
  1053.                       RingOfst structure a NULL pointer.  This could
  1054.                       occur if you use the AllocRingBuffer function or
  1055.                       something similar and the call to malloc fails.
  1056.  
  1057.                   R_BAUDERR - the passed baud rate in the BPDS string
  1058.                       was invalid.  Some possible reasons for this error
  1059.                       are leading spaces in the parameter string or use
  1060.                       of commas.  "115200N81" is correct. " 115200N81"
  1061.                       and "115,200N81" are both incorrect.
  1062.  
  1063.                   R_PARITYERR - an invalid character was found in the
  1064.                       parameter string where the parity should have
  1065.                       been.  Commas or spaces in the parameter string
  1066.                       are possible causes.  Valid parity settings are N
  1067.                       - none, E - even, or O - odd.  See R_BAUDERR.
  1068.  
  1069.                   R_DTABITERR - an invalid number of data bits was spec-
  1070.                       ified.  Only settings of 7 or 8 are supported.
  1071.  
  1072.                   R_STPBITERR - an invalid number of stop bits was spec-
  1073.                       ified.  Stop bits must be set to either 1 or 2.
  1074.  
  1075.                   R_IRQUSED - an attempt was made to open two ports that
  1076.                       use the same IRQ line.
  1077.  
  1078.                   R_VCTRUSED - an attempt was made to open two ports
  1079.                       that use the same interrupt vector.
  1080.  
  1081.                   R_NOPORT - an attempt was made to open more than 2
  1082.                       simultaneous ports.
  1083.  
  1084.                   R_PORTUSED - an attempt was made to open two ports
  1085.                       that have the same I/O address.
  1086.  
  1087.                   R_UARTERR - an attempt was made to open a port that is
  1088.                       stuck in an interrupt condition (see the notes on
  1089.                       problems with the WD16550 at the beginning of this
  1090.                       documentation ).
  1091.  
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.          async_open
  1098.          ---------------------------------------------------------------
  1099.  
  1100.          Remarks (16550 support):
  1101.  
  1102.                   This function now automatically detects the presence
  1103.                   of a 16550 UART and enables FIFO operation if one is
  1104.                   detected.  By ORing either 0x8000 or 0x4000 with the
  1105.                   ComBase argument, you can change the default of auto-
  1106.                   enabling FIFO mode.  If 0x8000 is ORed with the
  1107.                   ComBase argument (ex: 0x8000|0x3f8), no attempt is
  1108.                   made to detect a 16550 and no changes are made to the
  1109.                   mode of operation of the 16550 if one is present.  If
  1110.                   this bit is set, none of the functions or bits
  1111.                   relating to the 16550 UART will be valid.  If 0x4000
  1112.                   is ORed with the ComBase, the 16550 will be forced
  1113.                   into non-FIFO mode.
  1114.  
  1115.                   ORing 0x2000 with the ComBase parameter will open the
  1116.                   port with MSR interrupts disabled.  ORing the ComBase
  1117.                   parameter with 0x1000 will open the port with LSR
  1118.                   interrupts disabled.  See the notes on the WD16550 at
  1119.                   the beginning of this documentation for why this may
  1120.                   be desired and the side effects of opening a port with
  1121.                   MSR interrupts disabled.
  1122.  
  1123.                   When async_open is called, the FIFOs are momentarily
  1124.                   disabled and then re-enabled with the receive trigger
  1125.                   level set to 1 byte.  In versions of MCOMM prior to
  1126.                   5.40, the FIFOs were not reset if they were already
  1127.                   on.  Resetting the FIFOs was added to correct
  1128.                   occasional rare problems with the port not opening.
  1129.  
  1130.                     /* detect 16550, enable FIFOs if present */
  1131.                   async_open(PortPtr, 0x3f8, IRQ, Vector, Params);
  1132.  
  1133.                    /* do not attempt to detect 16550 */
  1134.                   async_open(PortPtr, 0x8000|0x3f8, IRQ, Vctr, Params);
  1135.  
  1136.                    /* detect 16550, disable FIFOs if present */
  1137.                   async_open(PortPtr, 0x4000|0x3f8, IRQ, Vctr, Params);
  1138.  
  1139.                    /* open port, disable MSR interrupts */
  1140.                   async_open(PortPtr, 0x2000|0x3f8, IRQ, Vctr, Params);
  1141.  
  1142.                    /* open port, disable MSR interrupts and FIFOs */
  1143.                   async_open(PortPtr, 0x6000|0x3f8, IRQ, Vctr, Params);
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.          async_open
  1151.          ---------------------------------------------------------------
  1152.  
  1153.          Remarks (versions previous to 5.00):
  1154.  
  1155.                   There are some major differences in the async_open
  1156.                   function in MCOMM5 and previous versions of the rou-
  1157.                   tines.  The two most major ones are that the parame-
  1158.                   ters passed to the function are different and it is
  1159.                   now necessary to allocate the memory for the ring
  1160.                   buffers before calling the function.  To make things
  1161.                   simpler, COM1 and COM2 are defined in COMM.H and the
  1162.                   function, AllocRingBuffer, is provided.  The COM1 and
  1163.                   COM2 definitions satisfy the requirements for the 2nd,
  1164.                   3rd, and 4th parameters required by the function.  For
  1165.                   ports other than the standard COM1 and COM2, it is
  1166.                   necessary to list the individual arguments.  The func-
  1167.                   tion, AllocRingBuffer, is provided in C source form on
  1168.                   the disk and included in the COMM_x libraries.  This
  1169.                   function allocates the ring buffer memory and initial-
  1170.                   izes the required port structure members.
  1171.  
  1172.                   The return values for async_open are different and may
  1173.                   have a different meaning than in earlier versions.
  1174.  
  1175.                   If a port is opened with an empty parameter string
  1176.                   (using "" for the parameters), then the port is opened
  1177.                   at its current settings and the port member BPDSstr is
  1178.                   set to the string representation of those values.
  1179.  
  1180.                   Async_open no longer checks the BIOS ram area at 40:0
  1181.                   to verify that a port actually exists.  There were too
  1182.                   many compatibles that did not store the proper values
  1183.                   there.
  1184.  
  1185.                   The maximum combined size of the receive and transmit
  1186.                   buffers for each port is 32K - 1.
  1187.  
  1188.                   FAR ring buffers in small and medium memory model
  1189.                   programs is now supported.  Use of FAR buffers does
  1190.                   not in any way affect the speed of the routines.
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.          async_peek
  1198.          ---------------------------------------------------------------
  1199.  
  1200.          Purpose: Indexed receive ring buffer look ahead function.
  1201.  
  1202.          Format:  int async_peek(port, index);
  1203.                    ASYNC *port;       Pointer to ASYNC structure
  1204.                    int index;         Index value
  1205.  
  1206.          Examples:
  1207.  
  1208.                   ASYNC *port;
  1209.                   char ch, buf[10];
  1210.                   int i;
  1211.  
  1212.                    /* peek next char in receive ring buffer */
  1213.                   ch = async_peek(port, 0);
  1214.  
  1215.                    /* peek next 10 chars in receive ring buffer */
  1216.                   for (i = 0; i < 10; i++)
  1217.                       buf[i] = async_peek(port, i);
  1218.  
  1219.          Returns: This function returns the character in the receive
  1220.                   ring buffer at the indexed position.  If an attempt is
  1221.                   made to peek deeper in the ring buffer than there are
  1222.                   characters in the ring buffer, -1 (0xffff) is
  1223.                   returned.
  1224.  
  1225.          Remarks: No characters are removed from the ring buffer by this
  1226.                   function.
  1227.  
  1228.                   The index value is 0 based.
  1229.  
  1230.                   To avoid confusing the character, '\0xff', from the
  1231.                   error return value, 0xffff, use an integer size
  1232.                   variable for the return value.  The character '\0xff'
  1233.                   is returned as 0x00ff and the error condition is
  1234.                   returned as 0xffff.
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.          async_regs
  1242.          ---------------------------------------------------------------
  1243.  
  1244.          Purpose: Provides direct access to the UART registers.
  1245.  
  1246.          Format:  int async_regs(port, reg_ofst, value);
  1247.                    ASYNC *port;       Pointer to ASYNC structure
  1248.                    int reg_ofst;      Offset of register from base adrs
  1249.                    int value;         Value to write or -1 if reading
  1250.  
  1251.          Examples:
  1252.  
  1253.                   ASYNC *port;
  1254.                   int LCRvalue;
  1255.  
  1256.                    /* read the line control register */
  1257.                   LCRvalue = async_regs(port, LCRreg, RDreg);
  1258.  
  1259.                    /* write a 0 to the modem control register */
  1260.                   async_regs(port, MCRreg, 0);
  1261.  
  1262.          Returns: When reading a register, the return value is the value
  1263.                   of the UART register that was read.  When writing a
  1264.                   register, the return value is undefined.
  1265.  
  1266.          Remarks: The following values for register offsets are defined
  1267.                   in COMM.H for use with async_regs:
  1268.                     RXreg, TXreg - receive & transmit regs, value = 0
  1269.                     IERreg - interrupt enable register,     value = 1
  1270.                     IIDreg - interrupt identification reg,  value = 2
  1271.                     FCRreg - FIFO control register          value = 2
  1272.                     LCRreg - line control register,         value = 3
  1273.                     MCRreg - modem control register,        value = 4
  1274.                     LSRreg - line status register,          value = 5
  1275.                     MSRreg - modem status register,         value = 6
  1276.                     LObaud - offset of low baud divisor,    value = 0
  1277.                     HIbaud - offset of high baud divisor,   value = 1
  1278.                   Also RDreg is defined as -1 for use when reading one
  1279.                   of the UART registers.  See the examples.  See
  1280.                   cautions on the following page before using this
  1281.                   function.
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.          async_regs
  1289.          ---------------------------------------------------------------
  1290.  
  1291.          Remarks (continued):
  1292.  
  1293.                   This function is provided primarily as a debugging
  1294.                   tool.  Reading or writing to the UART registers while
  1295.                   operating in an interrupt driven mode can cause
  1296.                   several types of problems.  Do not use this function
  1297.                   unless you know what you are doing.  Do not read the
  1298.                   RXreg, IIDreg, LSRreg, or MSRreg on an open port
  1299.                   except for debugging purposes.  Do not write any of
  1300.                   the registers.
  1301.  
  1302.                   The function may be used on a port that has not yet
  1303.                   been opened if the ComBase member of the port struc-
  1304.                   ture has been set.  When async_regs is used with an
  1305.                   unopened port the UART registers may be read or writ-
  1306.                   ten without restriction.
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.          async_reset
  1314.          ---------------------------------------------------------------
  1315.  
  1316.          Purpose: Clear parity error bit, framing error bit, character
  1317.                   overrun bit, receive buffer overflow bit, and break
  1318.                   signal received bit in the the Stat1 byte.
  1319.  
  1320.          Format:  void async_reset(port);
  1321.                    ASYNC *port;       Pointer to ASYNC structure
  1322.  
  1323.          Example:
  1324.  
  1325.                   ASYNC *port;
  1326.  
  1327.                   if (error)
  1328.                       async_reset(port);
  1329.  
  1330.  
  1331.          Returns: No return value
  1332.  
  1333.          Remarks: This function is implemented as a macro.  See also
  1334.                   async_rx and async_stat.
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.          async_restart
  1342.          ---------------------------------------------------------------
  1343.  
  1344.          Purpose: Re-initialize an already opened serial port
  1345.  
  1346.          Format:  void async_restart(port);
  1347.                    ASYNC *port;       Pointer to ASYNC structure
  1348.  
  1349.          Example:
  1350.  
  1351.                   ASYNC *port;
  1352.  
  1353.                   async_restart(port);
  1354.  
  1355.  
  1356.          Returns: No return value
  1357.  
  1358.          Remarks: Async_restart resets the interrupt vector, UART regis-
  1359.                   ters, and 8259 interrupt controller mask to the values
  1360.                   necessary for interrupt driven operation.  It also
  1361.                   flushes the receive and transmit buffers and resets
  1362.                   the Stat1 byte.  Use this function to restart a comm
  1363.                   port after spawning a program that may have altered
  1364.                   the interrupt vector, UART regs, or interrupt mask.
  1365.  
  1366.                   See also async_stop.
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.          async_rts
  1374.          ---------------------------------------------------------------
  1375.  
  1376.          Purpose: Sets or resets the Request to Send signal.
  1377.  
  1378.          Format:  void async_rts(port, flag);
  1379.                    ASYNC *port;       Pointer to ASYNC structure
  1380.                    int flag;          Set/Reset RTS flag
  1381.  
  1382.          Example:
  1383.  
  1384.                   ASYNC *port;
  1385.  
  1386.                   if (WantToDropRTS)
  1387.                       async_rts(port, 0);
  1388.                   else if (WantRTShigh)
  1389.                       async_rts(port, 1);
  1390.  
  1391.  
  1392.          Returns: No return value
  1393.  
  1394.          Remarks: The RTS signal is primarily used for hardware hand-
  1395.                   shaking.  When a port is first opened RTS is set HIGH
  1396.                   (enabled).  When the port is closed, it is restored to
  1397.                   the condition it was in when the port was opened.  To
  1398.                   force RTS low when closing a port, regardless of its
  1399.                   state when the port was opened, AND the port member,
  1400.                   OldMCR with NOT B_RTS.  To force RTS to remain high
  1401.                   when the port is closed, OR OldMCR with B_RTS.
  1402.  
  1403.                     Force low:    port->OldMCR &= ~B_RTS;
  1404.                                   async_close(port);
  1405.  
  1406.                     Force high:   port->OldMCR |= B_RTS;
  1407.                                   async_close(port);
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.          async_rx
  1415.          ---------------------------------------------------------------
  1416.  
  1417.          Purpose: Gets one character from the receive ring buffer.
  1418.  
  1419.          Format:  int async_rx(port);
  1420.                    ASYNC *port;       Pointer to ASYNC structure
  1421.  
  1422.          Examples:
  1423.  
  1424.                   ASYNC *port;
  1425.                   int rxch;
  1426.  
  1427.                   rxch = async_rx(port);       /* rxch == Stat1/char */
  1428.  
  1429.                   rxch = async_rx(port) & 0xff;      /* rxch == char */
  1430.  
  1431.                    /* chk if char available & process only if it was */
  1432.                   if (!((rxch = async_rx(port)) & B_RXEMPTY)
  1433.                       procRxdChar(rxch & 0xff);
  1434.  
  1435.          Returns: Async_rx returns the character received as the low
  1436.                   byte and the Stat1 status byte as the high byte.  If
  1437.                   the receive ring buffer was empty when async_rx was
  1438.                   called the low byte will be 0 and the high byte will
  1439.                   have the B_RXEMPTY bit set.  The Stat1 byte is a bit
  1440.                   mapped value that reflects parity errors, framing
  1441.                   errors, character overrun errors, receive buffer
  1442.                   overflow errors, receive buffer empty, break signal
  1443.                   received, and carrier lost.  If no receive errors
  1444.                   have occurred, a break signal has not been received,
  1445.                   and a carrier is present, Stat1 will be 0.
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.          async_rx
  1453.          ---------------------------------------------------------------
  1454.  
  1455.          Remarks: Error bits set in the Stat1 byte are not necessarily
  1456.                   associated with the character just taken out of the
  1457.                   receive ring buffer.  In fact, they probably are not.
  1458.                   The error bits are set when the error is detected and
  1459.                   reset when async_reset is called.  For example:
  1460.  
  1461.                    1) 20 bytes of data are received with no errors.
  1462.                    2) Async_rx has been called 10 times so 10 characters
  1463.                       have been taken out of the ring buffer and 10 of
  1464.                       the bytes with no errors are still in the buffer.
  1465.                    3) A parity error occurs on the next byte received
  1466.                       from the UART -- the 11th byte in the receive ring
  1467.                       buffer.
  1468.                    4) The next byte taken out of the buffer, which is
  1469.                       the first of the 10 remaining good bytes will have
  1470.                       the parity error bit in the Stat1 byte.  It will
  1471.                       remain set until async_reset is called.
  1472.  
  1473.                   If the 'ignore characters with errors' bit is set (see
  1474.                   async_ignerr), then characters that have either parity
  1475.                   or framing errors are never placed in the receive ring
  1476.                   buffer.  They are read from the UART and discarded.
  1477.                   The error bits in Stat1 are set regardless of the
  1478.                   setting of the 'ignore characters with errors' bit.
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.          async_rxblk
  1486.          ---------------------------------------------------------------
  1487.  
  1488.          Purpose: Retrieves a block of characters from the receive ring
  1489.                   buffer.
  1490.  
  1491.          Format:  int async_rxblk(port, buf, maxchars);
  1492.                    ASYNC *port;       Pointer to ASYNC structure
  1493.                    char *buf;         Buffer for received data
  1494.                    int maxchars;      Maximum number of chars to read
  1495.  
  1496.          Example:
  1497.  
  1498.                   ASYNC *port;
  1499.                   char buf[256];
  1500.                   int bytesRead;
  1501.  
  1502.                   bytesRead = async_rxblk(port, buf, sizeof(buf));
  1503.  
  1504.          Returns: Async_rxblk returns the number of bytes read.  This
  1505.                   value will be 'maxchars' if there are that many bytes
  1506.                   available in the receive buffer.  If there are not
  1507.                   'maxchars' in the receive buffer, the entire contents
  1508.                   of the receive buffer will be moved to 'buf' and the
  1509.                   return value will be the number of bytes that were in
  1510.                   the buffer.
  1511.  
  1512.          Remarks: Very fast way to read data.  See also async_rx and
  1513.                   async_rxblkch.
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.          async_rxblkch
  1521.          ---------------------------------------------------------------
  1522.  
  1523.          Purpose: Retrieve bytes from the receive ring buffer until the
  1524.                   specified character is found, 'maxchars' are read, or
  1525.                   the receive ring buffer is emptied.
  1526.  
  1527.          Format:
  1528.            int async_rxblkch(port, buf, maxchars, keychar, includekey);
  1529.             ASYNC *port;      Pointer to ASYNC structure
  1530.             char *buf;        Destination for bytes read
  1531.             int maxchars;     Maximum number of chars to read
  1532.             char keychar;     Character to scan for
  1533.             int includekey;   Flag set if 'keychar' is to be read also
  1534.  
  1535.          Example:
  1536.  
  1537.            ASYNC *port;
  1538.            char buf[256];
  1539.            int bytesRead;
  1540.            int foundkey;
  1541.  
  1542.            bytesRead = async_rxblkch(port, buf, sizeof(buf), '\n', 1);
  1543.            if (bytesRead < 0)
  1544.                bytesRead = -bytesRead, foundkey = TRUE;
  1545.             else
  1546.                foundkey = FALSE;
  1547.  
  1548.          Returns: This function returns the number of bytes read if the
  1549.                   'keychar' is not found.  If the 'keychar' is found the
  1550.                   2's complement of the number of bytes read is
  1551.                   returned.
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.          async_rxblkch
  1559.          ---------------------------------------------------------------
  1560.  
  1561.          Remarks: The 'includekey' flag, which is the last argument of
  1562.                   the function, determines whether or not the 'keychar'
  1563.                   is to be included if it is found.  If the flag is 1
  1564.                   and the 'keychar' is found it will be the last char-
  1565.                   acter in the user buffer.  If this flag is 0 and the
  1566.                   'keychar' is found, the 'keychar' is left in the re-
  1567.                   ceive ring buffer and will be the first character read
  1568.                   when you next call one of the async_rx type functions.
  1569.                   This can cause a problem if you set this flag to 0 and
  1570.                   the 'keychar' is the first character in the receive
  1571.                   buffer.  The function will return 0, which would seem
  1572.                   to indicate that there were no bytes in the buffer.
  1573.                   Actually the character was found but since you are not
  1574.                   taking it out of the ring buffer zero bytes are read.
  1575.                   There are two ways to check for this condition.  You
  1576.                   can first call async_rxcnt to verify there are bytes
  1577.                   in the receive buffer and then call async_rxblkch.  If
  1578.                   async_rxblkch returns 0, the 'keychar' is there and is
  1579.                   the first byte in the buffer.  The other method is to
  1580.                   use async_peek to see what the next character in the
  1581.                   receive buffer is before calling async_rxblkch.
  1582.  
  1583.                   A 2's complement value of the bytes read is returned
  1584.                   by async_rxblkch when the 'keychar' is found.  For
  1585.                   actual bytes use:
  1586.                       bytes = async_rxblkch( ....);
  1587.                       if (bytes < 0)
  1588.                           bytes = -bytes;
  1589.                   A byte count less than zero is the signal the
  1590.                   'keychar' was found.  (Except for the circumstance
  1591.                   noted in the previous paragraph).
  1592.  
  1593.                   See async_rx, async_rxblk, async_rxcnt, async_peek.
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.          async_rxcnt
  1601.          ---------------------------------------------------------------
  1602.  
  1603.          Purpose: Returns the number of bytes in the receive ring
  1604.                   buffer.
  1605.  
  1606.          Format:  int async_rxcnt(port);
  1607.                    ASYNC *port;       Pointer to ASYNC structure
  1608.  
  1609.          Example:
  1610.  
  1611.                   ASYNC *port;
  1612.  
  1613.                   BytesInRxBuf = async_rxcnt(port);
  1614.  
  1615.          Returns: Number of bytes in the receive ring buffer
  1616.  
  1617.          Remarks: This function is implemented as a macro.
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.          async_rxerr
  1625.          ---------------------------------------------------------------
  1626.  
  1627.          Purpose: Checks if a receive error has been detected.
  1628.  
  1629.          Format:  int async_rxerr(port);
  1630.                    ASYNC *port;       Pointer to ASYNC structure
  1631.  
  1632.          Example:
  1633.  
  1634.                   ASYNC *port;
  1635.                   int rxerr_status;
  1636.  
  1637.                   rxerr_status = async_rxerr(port);
  1638.  
  1639.          Returns: ZR if no receive errors have been detected, NZ if
  1640.                   receive error has been detected.
  1641.  
  1642.          Remarks: Types of receive errors that are detected by this
  1643.                   function are parity errors, framing errors, UART
  1644.                   receive register overflow, and receive ring buffer
  1645.                   overflow.  This information is also returned as the
  1646.                   high byte of the async_rx and async_stat functions.
  1647.                   This function is implemented as a macro.
  1648.  
  1649.                   See also async_rx, async_stat.
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.          async_rxflush
  1657.          ---------------------------------------------------------------
  1658.  
  1659.          Purpose: Empties out the receive ring buffer.
  1660.  
  1661.          Format:  void async_rxflush(port);
  1662.                    ASYNC *port;       Pointer to ASYNC structure
  1663.  
  1664.          Example:
  1665.  
  1666.                   ASYNC *port;
  1667.  
  1668.                   async_rxflush(port);
  1669.  
  1670.          Returns: This function does not have a return value
  1671.  
  1672.          Remarks: Clears the receive ring buffer and -- if a 16550 is
  1673.                   present in the system with its FIFOs activated --
  1674.                   resets the receiver FIFOs.  All data that was in the
  1675.                   buffer is lost.  If XON/XOFF flow control is being
  1676.                   used and an XOFF has been sent to the remote, this
  1677.                   function automatically sends an XON.  An XON is not
  1678.                   ALWAYS sent -- only if XFLOW control is in use and the
  1679.                   async interrupt routine has sent an XOFF.  It will not
  1680.                   clear false XOFFs the remote may have received.
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.          async_rxfree (5.40)
  1688.          ---------------------------------------------------------------
  1689.  
  1690.          Purpose: Returns the number of bytes left available in the
  1691.                   receive ring buffer for incoming characters.
  1692.  
  1693.          Format:  int async_rxfree(port);
  1694.                    ASYNC *port;       Pointer to ASYNC structure
  1695.  
  1696.          Example:
  1697.  
  1698.                   ASYNC *port;
  1699.  
  1700.                    RxBufFreeSpace = async_rxfree(port);
  1701.  
  1702.          Returns: Number of bytes that can be received without taking
  1703.                   any out before a receive buffer overflow will occur.
  1704.  
  1705.          Remarks: This function is implemented as a macro.
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.          async_setbpds
  1713.          ---------------------------------------------------------------
  1714.  
  1715.          Purpose: Change the baud rate, parity, number of data bits or
  1716.                   number of stop bits on an already opened port.
  1717.  
  1718.          Format:  int async_setbpds(port, params);
  1719.                    ASYNC *port;       Pointer to ASYNC structure
  1720.                    char *params;      Pointer to parameter string
  1721.  
  1722.          Example:
  1723.  
  1724.                   ASYNC *port;
  1725.                   int rcode;
  1726.  
  1727.                   rcode = async_setbpds(port, "2400E71");
  1728.  
  1729.          Returns: This function returns 0 if successful and the new
  1730.                   parameter string is copied to the port structure
  1731.                   member, BPDSstr.  Errors that can be returned are
  1732.                   R_BAUDERR, R_PARITYERR, R_DTABITERR, or R_STPBITERR.
  1733.                   If one of these error codes are returned, the port
  1734.                   settings are unchanged and the port member BPDSstr is
  1735.                   left unchanged.
  1736.  
  1737.                   See async_open for a more complete description of
  1738.                   these errors.
  1739.  
  1740.          Remarks: If 7 data bits is selected the StripMask is set to
  1741.                   strip the high bit off incoming data.  If 8 data bits
  1742.                   are selected the StripMask is disabled.
  1743.  
  1744.                   Valid baud rates are from 50 to 115200 baud.  Parity
  1745.                   may be 'E'ven, 'N'one, or 'O'dd.  The number of data
  1746.                   bits must be 7 or 8 and the number of stop bits must
  1747.                   be 1 or 2.  Do not use spaces, commas, or any other
  1748.                   type of punctuation in the parameter string.
  1749.  
  1750.                   See also async_open, async_strip.
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.          async_sndbrk
  1758.          ---------------------------------------------------------------
  1759.  
  1760.          Purpose: Enable or disable a break signal
  1761.  
  1762.          Format:  void async_sndbrk(port, Brkflag);
  1763.                    ASYNC *port;       Pointer to ASYNC structure
  1764.                    int Brkflag;       Set/Reset break signal flag
  1765.  
  1766.          Example:
  1767.  
  1768.                   ASYNC *port;
  1769.  
  1770.                    /* send break for 50 msec */
  1771.                   async_sndbrk(port, 1); /* enable break signal */
  1772.                   delay(50MSEC);         /* your delay function */
  1773.                   async_sndbrk(port, 0); /* disable break signal */
  1774.  
  1775.  
  1776.          Returns: No return value
  1777.  
  1778.          Remarks: This function causes the UART to send a continuous
  1779.                   break signal if it is called with the flag set to 1.
  1780.                   It must be called again with the flag set to 0 to
  1781.                   disable the break signal.
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.          async_stat
  1789.          ---------------------------------------------------------------
  1790.  
  1791.          Purpose: Get the current status of a port
  1792.  
  1793.          Format:  int async_stat(port, mask);
  1794.                    ASYNC *port;       Pointer to ASYNC structure
  1795.                    int mask;          Mask applied to return value
  1796.  
  1797.          Examples:
  1798.  
  1799.                   ASYNC *port;
  1800.                   int status;
  1801.  
  1802.                    /* status = all status bits */
  1803.                   status = async_stat(port, 0xffff);
  1804.  
  1805.                    /* check for XOFF received condition */
  1806.                   if (async_stat(port, B_XRXD))
  1807.                       do_something();
  1808.  
  1809.  
  1810.          Returns: Returns Stat1/Stat2 status bits after masking them
  1811.                   with the passed mask value.  Stat1 is the high byte
  1812.                   and Stat2 is the low byte of the return value.
  1813.  
  1814.                   Stat1 bit map:
  1815.                       Bit 7 = set if no carrier present
  1816.                       Bit 6 = receive ring buffer empty
  1817.                       Bit 5 = used by interrupt routines (always 0)
  1818.                       Bit 4 = break signal was detected
  1819.                       Bit 3 = framing error was detected
  1820.                       Bit 2 = parity error was detected
  1821.                       Bit 1 = character overrun error was detected
  1822.                       Bit 0 = receive ring buffer has overflowed
  1823.  
  1824.                   Stat2 bit map:
  1825.                       Bit 7 = carrier detect monitored for flow control
  1826.                       Bit 6 = XOFF rx'd or hardware flow control active
  1827.                       Bit 5 = data set ready monitored for flow control
  1828.                       Bit 4 = clear to send monitored for flow control
  1829.                       Bit 3 = transmit ring buffer is empty
  1830.                       Bit 2 = an XOFF has been sent by interrupt handler
  1831.                       Bit 1 = an XOFF has been received
  1832.                       Bit 0 = using XON/XOFF flow control
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.          async_stat
  1840.          ---------------------------------------------------------------
  1841.  
  1842.          Remarks: For some situations, it is more efficient to use one
  1843.                   of the other library functions targeted specifically
  1844.                   for the information you want.  For instance, instead
  1845.                   of calling:
  1846.                        async_stat(port, B_XRXD);
  1847.                   use:
  1848.                        async_xrxd(port);
  1849.  
  1850.                   The information in the Stat1 byte is also returned as
  1851.                   the high byte of the async_rx function.  Bits 0-4 of
  1852.                   Stat1 remain set until cleared by the async_reset
  1853.                   function.
  1854.  
  1855.                   Not all bits in the Stat2 and Stat1 port structure
  1856.                   members are kept updated on a constant basis so do not
  1857.                   try to check a condition by testing the Stat1 or Stat2
  1858.                   values in the ASYNC structure.  Use one of the docu-
  1859.                   mented functions or macros to be sure of getting the
  1860.                   correct result.
  1861.  
  1862.  
  1863.  
  1864.  
  1865.  
  1866.  
  1867.          async_stop
  1868.          ---------------------------------------------------------------
  1869.  
  1870.          Purpose: Temporarily disables interrupt driven operation of an
  1871.                   already opened port.
  1872.  
  1873.          Format:  void async_stop(port);
  1874.                    ASYNC *port;       Pointer to ASYNC structure
  1875.  
  1876.          Example:
  1877.  
  1878.                   ASYNC *port;
  1879.                   int x, inhdl, outhdl, errhdl;
  1880.  
  1881.                   async_stop(port);               /* release port */
  1882.                    /* redirect console to async port */
  1883.                   x = open("COM1", O_RDWR|O_BINARY);
  1884.                   inhdl = dup(0);  outhdl = dup(1);  errhdl = dup(2);
  1885.                   dup2(x, 0);  dup2(x, 1);  dup2(x, 2);
  1886.                    /* run a redirected DOS shell */
  1887.                   spawnlp(P_WAIT, "COMMAND.COM", "COMMAND.COM", NULL);
  1888.                    /* restore stdin, stdout, stderr */
  1889.                   close(x);
  1890.                   dup2(inhdl, 0);   close(inhdl);
  1891.                   dup2(outhdl, 1);  close(outhdl);
  1892.                   dup2(errhdl, 2);  close(errhdl);
  1893.                   async_restart(port);   /* regain control of port */
  1894.  
  1895.          Returns: No return value
  1896.  
  1897.          Remarks: Call this function before spawning a program that will
  1898.                   be doing its own port I/O, such as an external commun-
  1899.                   ications program or a redirected DOS shell.  After the
  1900.                   other application has completed, call async_restart to
  1901.                   re-enable interrupt operation.
  1902.  
  1903.                   This function disables interrupts for the named port
  1904.                   by clearing UART's interrupt enable register and the
  1905.                   OUT2 bit of its modem control register.
  1906.  
  1907.                   See also async_restart.
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.          async_strip
  1915.          ---------------------------------------------------------------
  1916.  
  1917.          Purpose: Set the strip mask for received characters.
  1918.  
  1919.          Format:  void async_strip(port, mask);
  1920.                    ASYNC *port;       Pointer to ASYNC structure
  1921.                    char mask;         Strip mask
  1922.  
  1923.          Example:
  1924.  
  1925.                   ASYNC *port;
  1926.  
  1927.                   async_strip(port, '\x7f');
  1928.  
  1929.          Returns: No return value
  1930.  
  1931.          Remarks: The strip mask is automatically set to 0x7f when the
  1932.                   parameters are set for 7 data bits and to 0xff when 8
  1933.                   data bits are used.  All incoming data is ANDed with
  1934.                   the strip mask before it is placed in the receive ring
  1935.                   buffer.  This function is implemented as a macro.
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.          async_tx
  1943.          ---------------------------------------------------------------
  1944.  
  1945.          Purpose: Send 1 character to a port.
  1946.  
  1947.          Format:  int async_tx(port, ch);
  1948.                    ASYNC *port;       Pointer to ASYNC structure
  1949.                    char ch;           Character to transmit
  1950.  
  1951.          Example:
  1952.  
  1953.                   ASYNC *port;
  1954.  
  1955.                    /* send a CR/LF to a port */
  1956.                   async_tx(port, '\r');
  1957.                   async_tx(port, '\n');
  1958.  
  1959.  
  1960.          Returns: Returns the number of bytes left available in the
  1961.                   transmit ring buffer unless the ring buffer was full
  1962.                   when the function was called.  R_TXERR is returned if
  1963.                   the transmit ring buffer was full and the character
  1964.                   that was to be transmitted is not placed in the ring
  1965.                   buffer.
  1966.  
  1967.          Remarks: The error return value, R_TXERR, is a negative number.
  1968.                   The bytes free return value can never be negative.
  1969.  
  1970.                   See also async_txblk, async_txfree.
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.          async_txblk
  1978.          ---------------------------------------------------------------
  1979.  
  1980.          Purpose: Send a block of characters to a port.
  1981.  
  1982.          Format:  int async_txblk(port, buf, count);
  1983.                    ASYNC *port;       Pointer to ASYNC structure
  1984.                    char *buf;         Pointer to block to transmit
  1985.                    int count;         Size of block in bytes
  1986.  
  1987.          Examples:
  1988.  
  1989.                   ASYNC *port;
  1990.                   char buf[128];
  1991.                   static char *msg = "Send this message\r\n");
  1992.  
  1993.                   put_data_in_buf();
  1994.                   async_txblk(port, buf, sizeof(buf));
  1995.                   async_txblk(port, msg, strlen(msg));
  1996.  
  1997.          Returns: Returns the number of bytes left available in the
  1998.                   transmit ring buffer unless the ring buffer would not
  1999.                   hold the entire block when the function was called.
  2000.                   R_TXERR is returned if there was no room for the
  2001.                   block and none of the bytes in the block are sent.
  2002.  
  2003.          Remarks: This function is much faster than using repeated calls
  2004.                   to async_tx when multiple bytes are being transmitted.
  2005.                   The error return value, R_TXERR, is a negative number.
  2006.                   The bytes free return value can never be negative.
  2007.  
  2008.                   See also async_tx, async_txfree.
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.          async_txcnt (5.40)
  2016.          ---------------------------------------------------------------
  2017.  
  2018.          Purpose: Returns the number of bytes in the transmit ring
  2019.                   buffer.
  2020.  
  2021.          Format:  int async_txcnt(port);
  2022.                    ASYNC *port;       Pointer to ASYNC structure
  2023.  
  2024.          Example:
  2025.  
  2026.                   ASYNC *port;
  2027.  
  2028.                   BytesInTxBuf = async_txcnt(port);
  2029.  
  2030.          Returns: Number of untransmitted bytes in the transmit ring
  2031.                   buffer.
  2032.  
  2033.          Remarks: This function is implemented as a macro.  If a 16550
  2034.                   is in the system with its FIFOs active, there may be
  2035.                   up to 16 (depends on what async_FIFOtxlvl is set at --
  2036.                   the default is 3 bytes) more bytes of untransmitted
  2037.                   data in the 16550 FIFOs plus 1 byte in the UART
  2038.                   transmit hold register.  With no 16550 there may still
  2039.                   be up to 2 untransmitted bytes -- one in the UART's
  2040.                   transmit hold register and one in the UART's transmit
  2041.                   shift register.  To monitor for a transmit buffer
  2042.                   empty condition use async_txempty.
  2043.  
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.          async_txempty
  2050.          ---------------------------------------------------------------
  2051.  
  2052.          Purpose: Checks if transmit ring buffer is empty.
  2053.  
  2054.          Format:  int async_txempty(port);
  2055.                    ASYNC *port;       Pointer to ASYNC structure
  2056.  
  2057.          Example:
  2058.  
  2059.                   ASYNC *port;
  2060.  
  2061.                    /* wait for transmit ring buffer to empty out */
  2062.                   while (!async_txempty(port))
  2063.                       ;
  2064.  
  2065.          Returns: NZ if the transmit ring buffer is empty, ZR if the
  2066.                   buffer still has characters to be transmitted.
  2067.  
  2068.          Remarks: This function is implemented as a macro.  If a 16550
  2069.                   is in the system with its FIFOs active, there may be
  2070.                   up to 16 (depends on what async_FIFOtxlvl is set at --
  2071.                   the default is 3 bytes) more bytes of untransmitted
  2072.                   data in the 16550 FIFOs plus 1 byte in the UART
  2073.                   transmit hold register.  With no 16550 there may still
  2074.                   be up to 2 untransmitted bytes -- one in the UART's
  2075.                   transmit hold register and one in the UART's transmit
  2076.                   shift register.
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.          async_txflush
  2084.          ---------------------------------------------------------------
  2085.  
  2086.          Purpose: Flushes the transmit ring buffer.
  2087.  
  2088.          Format:  void async_txflush(port);
  2089.                    ASYNC *port;       Pointer to ASYNC structure
  2090.  
  2091.          Example:
  2092.  
  2093.                   ASYNC *port;
  2094.  
  2095.                   async_txflush(port);
  2096.  
  2097.  
  2098.          Returns: No return value
  2099.  
  2100.          Remarks: Clears the transmit ring buffer and -- if a 16550
  2101.                   operating in FIFO mode is in the system -- resets the
  2102.                   transmit FIFOs.  All characters in the buffer that
  2103.                   have not been transmitted are lost.
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.          async_txfree
  2111.          ---------------------------------------------------------------
  2112.  
  2113.          Purpose: Returns the number of bytes left available in the
  2114.                   transmit ring buffer.
  2115.  
  2116.          Format:  int async_txfree(port);
  2117.                    ASYNC *port;       Pointer to ASYNC structure
  2118.  
  2119.          Example:
  2120.  
  2121.                   ASYNC *port;
  2122.                   int tx_bytes_available;
  2123.  
  2124.                   tx_bytes_available = async_txfree(port);
  2125.  
  2126.  
  2127.          Returns: Number of bytes of free space left in the transmit
  2128.                   buffer.
  2129.  
  2130.          Remarks: The number of free bytes left in the transmit ring
  2131.                   buffer is also the return value of async_tx and
  2132.                   async_txblk.  This function is implemented as a macro.
  2133.  
  2134.  
  2135.  
  2136.  
  2137.  
  2138.  
  2139.          async_xany
  2140.          ---------------------------------------------------------------
  2141.  
  2142.          Purpose: Checks if accepting the first character after an XOFF
  2143.                   is received as the XON character.  DOES NOT enable any
  2144.                   character XON (use async_xflow).
  2145.  
  2146.          Format:  int async_xany(port);
  2147.                    ASYNC *port;       Pointer to ASYNC structure
  2148.  
  2149.          Example:
  2150.  
  2151.                   ASYNC *port;
  2152.                   int rcode;
  2153.  
  2154.                   rcode = async_xany(port);
  2155.  
  2156.          Returns: Not zero if first character after an XOFF is to be
  2157.                   treated as an XON.  Zero if a real XON is required to
  2158.                   clear an XOFF.
  2159.  
  2160.          Remarks: This function is implemented as a macro.  See also
  2161.                   async_xflow.
  2162.  
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.          async_xflow
  2169.          ---------------------------------------------------------------
  2170.  
  2171.          Purpose: Enables/disables use of XON/XOFF flow control.
  2172.  
  2173.          Format:  void async_xflow(port, flag);
  2174.                    ASYNC *port;       Pointer to ASYNC structure
  2175.                    int flag;          Enable/Disable & any char XON flag
  2176.  
  2177.          Examples:
  2178.  
  2179.                   ASYNC *port;
  2180.  
  2181.                   async_xflow(port, B_XUSE); /* use flow control */
  2182.                   async_xflow(port, 0);      /* disable flow control */
  2183.  
  2184.                    /* use XON/XOFF flow control with any char being
  2185.                       accepted as an XON */
  2186.                   async_xflow(port, B_XUSE | B_XONANY);
  2187.  
  2188.                    /* enable XON/XOFF on transmit side only */
  2189.                   async_xflow(port, B_XUSET);
  2190.  
  2191.                    /* enable XON/XOFF on receive side only */
  2192.                   async_xflow(port, B_XUSER);
  2193.  
  2194.          Returns: No return value
  2195.  
  2196.          Remarks: Passing B_XUSET enables the transmission of XON/XOFF
  2197.                   characters when the receive buffer fills to the 'trip'
  2198.                   levels discussed in the following paragraph.  Incoming
  2199.                   XON/XOFFs are not regarded as flow control characters
  2200.                   and are stored in the ring buffer.  Passing B_XUSER,
  2201.                   enables recognition of received XON/XOFFs as flow
  2202.                   characters but does not enable transmission of
  2203.                   XON/XOFF at the trip levels.  If B_XUSE is passed,
  2204.                   both transmission and recognition of XON/XOFF as flow
  2205.                   characters is enabled (the same as B_XUSET | B_XUSER).
  2206.                   ORing B_XONANY with either B_XUSE or B_XUSER causes
  2207.                   the first character received after an XOFF to be
  2208.                   treated as the XON unless that character is another
  2209.                   XOFF.  Passing zero as the flag disables XON/XOFF flow
  2210.                   control.  The default is no flow control.
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.          async_xflow
  2218.          ---------------------------------------------------------------
  2219.  
  2220.          Remarks (continued):
  2221.  
  2222.                   The port structure member, XoffTrip, determines when
  2223.                   an XOFF will be sent.  Whenever the number of bytes
  2224.                   left available in receive buffer falls below XoffTrip,
  2225.                   an XOFF is sent.  The default value of XoffTrip is 25%
  2226.                   of the size of the receive buffer so an XOFF is sent
  2227.                   whenever the receive buffer is 75% full.
  2228.  
  2229.                   The port structure member, XonTrip, determines when an
  2230.                   XON will be sent.  Whenever the number of bytes left
  2231.                   available in the receive buffer rises above XonTrip,
  2232.                   an XON will be sent.  Its default value is 50% of the
  2233.                   size of the receive buffer.
  2234.  
  2235.                   The port structure member, XTxRptInit, determines how
  2236.                   many bytes may be received after an XOFF is sent
  2237.                   before another XOFF is sent.  Its default value is
  2238.                   6.25% of the size of the receive buffer or 160 bytes,
  2239.                   whichever is less.
  2240.  
  2241.                   XoffTrip, XonTrip, and XTxRptInit may all be changed
  2242.                   from their default values by directly accessing the
  2243.                   port structure.  To do this:
  2244.  
  2245.                       ASYNC *port;
  2246.                      /* send XOFF when 300 bytes left in rx ring buf */
  2247.                       port->XoffTrip = 300;
  2248.                      /* send XON when 350 bytes left in rx ring buf */
  2249.                       port->XonTrip = 350;
  2250.  
  2251.                   Be sure to keep the XonTrip level higher than the
  2252.                   XoffTrip level.  The values are for bytes left
  2253.                   available not bytes used.
  2254.  
  2255.                   The XTxRptInit value is used to automatically send
  2256.                   another XOFF in the event the first one was ignored.
  2257.                   Instead of sending an XOFF character everytime another
  2258.                   character is received, the interrupt routines wait for
  2259.                   'XTxRptInit' characters to be received and then repeat
  2260.                   the XOFF.  If this value is set to low some systems
  2261.                   that allow any character to be an XON will treat the
  2262.                   repeated XOFF character as an XON.
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.          async_xoffclr
  2270.          ---------------------------------------------------------------
  2271.  
  2272.          Purpose: Manually clears an XOFF received condition
  2273.  
  2274.          Format:  void async_xoffclr(port);
  2275.                    ASYNC *port;       Pointer to ASYNC structure
  2276.  
  2277.          Example:
  2278.  
  2279.                   ASYNC *port;
  2280.  
  2281.                   async_xoffclr(port);
  2282.  
  2283.          Returns: No return value
  2284.  
  2285.          Remarks: Async_xoffclr has the same effect as if the remote
  2286.                   system had sent an XON.  This will unstop the system
  2287.                   in the event a false XOFF is received or the remote's
  2288.                   XON was lost.  Use this function with caution.  Unless
  2289.                   something goes wrong, the remote will clear XOFF cond-
  2290.                   itions automatically by sending an XON.  If an XOFF is
  2291.                   manually cleared, the remote site may be overran and
  2292.                   lose data.  For use only when XON/XOFF flow control
  2293.                   has been activated.
  2294.  
  2295.                   See also async_xoffset.
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.          async_xoffset
  2303.          ---------------------------------------------------------------
  2304.  
  2305.          Purpose: Manually sets an XOFF received condition
  2306.  
  2307.          Format:  void async_xoffset(port);
  2308.                    ASYNC *port;       Pointer to ASYNC structure
  2309.  
  2310.          Example:
  2311.  
  2312.                   ASYNC *port;
  2313.  
  2314.                   async_xoffset(port);
  2315.  
  2316.          Returns: No return value
  2317.  
  2318.          Remarks: Forces the local site to act as though an XOFF had
  2319.                   been received.  Transmit interrupts are disabled until
  2320.                   the remote sends an XON or you call async_xoffclr.
  2321.                   For use only when XON/XOFF flow control has been
  2322.                   activated.
  2323.  
  2324.                   See also async_xoffclr.
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.          async_xrxd
  2332.          ---------------------------------------------------------------
  2333.  
  2334.          Purpose: Check if an XOFF has been received and has activated a
  2335.                   flow control halt.
  2336.  
  2337.          Format:  int async_xrxd(port);
  2338.                    ASYNC *port;       Pointer to ASYNC structure
  2339.  
  2340.          Example:
  2341.  
  2342.                   ASYNC *port;
  2343.                   int rcode;
  2344.  
  2345.                   rcode = async_xrxd(port);
  2346.  
  2347.          Returns: Not zero if an XOFF has been received and an XON has
  2348.                   not been received to clear it.  Returns zero if XOFF
  2349.                   flow halt is not currently active.
  2350.  
  2351.          Remarks: This function is implemented as a macro.  See also
  2352.                   async_xoffclr, async_xtxd.
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.          async_xtxd
  2360.          ---------------------------------------------------------------
  2361.  
  2362.          Purpose: Check if an XOFF has been sent
  2363.  
  2364.          Format:  int async_xtxd(port);
  2365.                    ASYNC *port;       Pointer to ASYNC structure
  2366.  
  2367.          Example:
  2368.  
  2369.                   ASYNC *port;
  2370.                   int rcode;
  2371.  
  2372.                   rcode = async_xtxd(port);
  2373.  
  2374.          Returns: Not zero if an XOFF has not been sent by the receive
  2375.                   interrupt routine and an XON has not been sent to
  2376.                   clear it.  Returns zero if an XOFF has not been sent.
  2377.  
  2378.          Remarks: This function is implemented as a macro.  See also
  2379.                   async_xoffclr, async_xrxd.
  2380.  
  2381.  
  2382.  
  2383.  
  2384.  
  2385.  
  2386.          async_xuse
  2387.          ---------------------------------------------------------------
  2388.  
  2389.          Purpose: Check if XON/XOFF protocol is currently being used
  2390.  
  2391.          Format:  int async_xuse(port);
  2392.                    ASYNC *port;       Pointer to ASYNC structure
  2393.  
  2394.          Example:
  2395.  
  2396.                   ASYNC *port;
  2397.  
  2398.                   rcode = async_xuse(port);
  2399.  
  2400.          Returns: Not zero if XON/XOFF protocol is being used on either
  2401.                   the transmit or receive sides, zero if XON/XOFF flow
  2402.                   is not being used at all.
  2403.  
  2404.          Remarks: This function is implemented as a macro.  See
  2405.                   async_xflow, async_xuset, async_xuser.
  2406.  
  2407.  
  2408.  
  2409.  
  2410.  
  2411.  
  2412.          async_xuser
  2413.          ---------------------------------------------------------------
  2414.  
  2415.          Purpose: Check if XON/XOFF protocol is enabled on the receive
  2416.                   side (receiver recognizes XON/XOFF as flow control).
  2417.  
  2418.          Format:  int async_xuser(port);
  2419.                    ASYNC *port;       Pointer to ASYNC structure
  2420.  
  2421.          Example:
  2422.  
  2423.                   ASYNC *port;
  2424.  
  2425.                   rcode = async_xuser(port);
  2426.  
  2427.          Returns: Not zero if XON/XOFF protocol is being used on the
  2428.                   receive side, zero if it is not.
  2429.  
  2430.          Remarks: This function is implemented as a macro.  See
  2431.                   async_xflow, async_xuset, async_xuse.
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.          async_xuset
  2439.          ---------------------------------------------------------------
  2440.  
  2441.          Purpose: Check if XON/XOFF protocol is enabled on the transmit
  2442.                   side (transmitter sends XOFF/XON as receive buffer
  2443.                   bytes available crosses trip levels).
  2444.  
  2445.          Format:  int async_xuset(port);
  2446.                    ASYNC *port;       Pointer to ASYNC structure
  2447.  
  2448.          Example:
  2449.  
  2450.                   ASYNC *port;
  2451.  
  2452.                   rcode = async_xuset(port);
  2453.  
  2454.          Returns: Not zero if XON/XOFF protocol is being used on the
  2455.                   transmit side, zero if it is not.
  2456.  
  2457.          Remarks: This function is implemented as a macro.  See
  2458.                   async_xflow, async_xuser, async_xuse.
  2459.  
  2460.